package co.baiku.boot.weixin;

import co.baiku.boot.AjavaerCache;
import co.baiku.boot.common.message.Message;
import co.baiku.boot.common.tools.*;
import co.baiku.boot.common.type.TimeFormat;
import co.baiku.boot.config.QyWeixinAppConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Component
@ConditionalOnProperty("ajavaer.weixin.qy.app.corpid")
public class QyWeixinApp {

    private Logger log = LoggerFactory.getLogger(QyWeixinApp.class);
    @Resource
    private QyWeixinAppConfig qyWeixinAppConfig;

    private static final String accessTokenKey = "qiye:weixin:jssdk:{0}:access_token";

    /**
     * 企业微信,发送微信消息
     *
     * @param toUser
     * @param content
     * @return
     */
    public Message send(String env, String txId, String toUser, String content) {
        return send(env, "", txId, toUser, content);
    }

    /**
     * 企业微信,发送微信消息
     *
     * @param toUser
     * @param content
     * @return
     */
    public Message send(String env, String applicationName, String txId, String toUser, String content) {
        String key = "qiye:weixin:sms:md5:" + EncryptTools.md5(content);
        try {
            long sendCount = AjavaerCache.redis().increment(key, 1);
            if (sendCount >= 2) {
                return Message.fail("发送消息:" + txId + "太频繁,此次消息未发出");
            }
            String token = getToken(qyWeixinAppConfig.getAgentId());
            if (StringTools.isNotBlank(token)) {
                AjavaerCache.redis().increment(key, 1);
                content = "Env：" + env
                        + (StringTools.isNotBlank(applicationName) ? ("\nApplicationName：" + applicationName) : "")
                        + "\nTxId：" + txId
                        + "\nIp:" + IpTools.getHostIpAddr()
                        + "\nTime:" + TimeFormat.toStr(LocalDateTime.now(), TimeFormat.DATETIME)
                        + "\nError:" + content;
                String sendUrl = qyWeixinAppConfig.getSendMsgUrl(token);
                return HttpTools.postJson(sendUrl, "{\"touser\" : \"" + StringTools.nvl(toUser, qyWeixinAppConfig.getUserList()) + "\",\"msgtype\" : \"text\",\"agentid\" : " + qyWeixinAppConfig.getAgentId() + ",\"text\" : { \"content\" : \"" + content + "\"},\"safe\":0}");
            } else {
                return Message.fail("token不存在");
            }
        } finally {
            AjavaerCache.redis().expire(key, 60, TimeUnit.SECONDS);
        }
    }

    private String getToken(String appid) {
        String token = AjavaerCache.redis().get(StringTools.format(accessTokenKey, appid));
        if (StringTools.isNotBlank(token)) {
            return token;
        }
        return refreshToken();
    }

    private String refreshToken() {
        String token = StringTools.format(qyWeixinAppConfig.getGetTokenUrl(), qyWeixinAppConfig.getCorpid(), qyWeixinAppConfig.getSecret());
        Message message = HttpTools.get(token);
        String accessToken = "";
        log.info("weixin message:" + JsonTools.beanToJson(message));
        if (message.isSuccess()) {
            Map<String, Object> tokenMessage = JsonTools.jsonToBean(message.getResult().toString(), Map.class);
            Integer errcode = (Integer) tokenMessage.get("errcode");
            if (errcode == null || errcode == 0) {
                accessToken = (String) tokenMessage.get("access_token");
                Integer expiresIn = (Integer) tokenMessage.get("expires_in");
                AjavaerCache.redis().put(StringTools.format(accessTokenKey, qyWeixinAppConfig.getAgentId()), accessToken, expiresIn - 100, TimeUnit.SECONDS);
                log.info(StringTools.format("token 刷新成功:{1}", token));
            }
        } else {
            log.error("刷新token失败:" + JsonTools.beanToJson(message));
        }
        return accessToken;
    }
}
